package com.example.Windturbine.Service.Impl;

import com.example.Windturbine.Controller.ViewObject.ResultGraphVO.ResultNode;
import com.example.Windturbine.Controller.ViewObject.ResultVO.ListResultVO;
import com.example.Windturbine.Controller.ViewObject.ResultVO.PartGraphVO;
import com.example.Windturbine.Dao.*;
import com.example.Windturbine.DataObject.LCAResultDO;
import com.example.Windturbine.DataObject.PartResultDO;
import com.example.Windturbine.DataObject.ProductInfoDO;
import com.example.Windturbine.Error.BusinessException;
import com.example.Windturbine.Error.EmBusinessError;
import com.example.Windturbine.Service.PartResultService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.PriorityQueue;


/**
 * @Author 丁永新
 * @Date 2021/12/22
 */
@Service
public class PartResultServiceImpl implements PartResultService {


    @Resource
    PartResultDOMapper partResultDOMapper;


    @Resource
    ProductDOMapper productDOMapper;

    @Resource
    ProductInfoDOMapper productInfoDOMapper;

    @Resource
    LCAResultDOMapper lcaResultDOMapper;

    @Override
    public List<ListResultVO> getResult(Integer cal_id, Integer product_id) throws BusinessException {
        List<ListResultVO> lists=new ArrayList<>();

        List<PartResultDO> partResultDOS = partResultDOMapper.selectByCaliddAndProductid(cal_id, product_id);

        if(partResultDOS==null){
            throw new BusinessException(EmBusinessError.UNKNOWN_ERROR,"获取计算结果失败！");
        }

        for(PartResultDO i:partResultDOS){
            ListResultVO temp=new ListResultVO();
            Integer partid=i.getPartId();
            //查询该结果对应的零件
            ProductInfoDO productInfoDO=productInfoDOMapper.selectByPrimaryKey(partid);
            if(productInfoDO==null){
                throw new BusinessException(EmBusinessError.UNKNOWN_ERROR,"获取零件信息失败！");
            }
            temp.setName(productInfoDO.getNameInfo());
            temp.setSerial(productInfoDO.getSerialInfo());
            String order=productInfoDO.getOrderInfo();
            String[] orders=order.split("\\.");
            int n=orders.length;
            temp.setType(n+" 级零件");

            //设置零件的其他几个阶段的数据
            Integer id1=i.getRawmaterialMiningStage();
            Integer id2=i.getPartTransportationStage();
            Integer id3=i.getManufacturingStage();
            Integer id6=i.getRecoveryStage();

            //获取其他各个阶段的结果
            LCAResultDO d1=lcaResultDOMapper.selectByPrimaryKey(id1);
            LCAResultDO d2=lcaResultDOMapper.selectByPrimaryKey(id2);
            LCAResultDO d3=lcaResultDOMapper.selectByPrimaryKey(id3);
            LCAResultDO d6=lcaResultDOMapper.selectByPrimaryKey(id6);

            //计算PED
            BigDecimal ped=d1.getPed().add(d2.getPed()).add(d3.getPed()).add(d6.getPed());
            //计算GWP
            BigDecimal gwp=d1.getGwp().add(d2.getGwp()).add(d3.getGwp()).add(d6.getGwp());
            //计算AP
            BigDecimal ap=d1.getAp().add(d2.getAp()).add(d3.getAp()).add(d6.getAp());
            //计算EP
            BigDecimal ep=d1.getEp().add(d2.getEp()).add(d3.getEp()).add(d6.getEp());
            //计算POCP
            BigDecimal pocp=d1.getPocp().add(d2.getPocp()).add(d3.getPocp()).add(d6.getPocp());
            //计算ODP
            BigDecimal odp=d1.getOdp().add(d2.getOdp()).add(d3.getOdp()).add(d6.getOdp());
            //计算Green value
            BigDecimal greenvalue=d1.getGreenvalue().add(d2.getGreenvalue()).add(d3.getGreenvalue()).add(d6.getGreenvalue());

            temp.setAp(ap);
            temp.setEp(ep);
            temp.setGreenvalue(greenvalue);
            temp.setGwp(gwp);
            temp.setOdp(odp);
            temp.setPocp(pocp);
            temp.setPed(ped);
            lists.add(temp);
        }
        return lists;
    }



    @Override
    public List<PartGraphVO> getGraphResult(Integer cal_id, Integer product_id) throws BusinessException {
        List<PartGraphVO> lists=new ArrayList<>();
        List<PartResultDO> partResultDOS = partResultDOMapper.selectByCaliddAndProductid(cal_id, product_id);
        if(partResultDOS==null){
            throw new BusinessException(EmBusinessError.UNKNOWN_ERROR,"获取图形数据失败！");
        }



        for(PartResultDO i:partResultDOS){
            PartGraphVO temp=new PartGraphVO();
            Integer partid=i.getPartId();
            //查询该结果对应的零件
            ProductInfoDO productInfoDO=productInfoDOMapper.selectByPrimaryKey(partid);

            temp.setSerial(productInfoDO.getSerialInfo());
            String order=productInfoDO.getOrderInfo();
            String[] orders=order.split("\\.");
            int n=orders.length;
            temp.setType(n+" 级零件");
            temp.setName(n+" 级零件-"+productInfoDO.getNameInfo());

            //设置零件的其他几个阶段的数据
            Integer id1=i.getRawmaterialMiningStage();
            Integer id2=i.getPartTransportationStage();
            Integer id3=i.getManufacturingStage();
            Integer id6=i.getRecoveryStage();

            //获取其他各个阶段的结果
            LCAResultDO d1=lcaResultDOMapper.selectByPrimaryKey(id1);
            LCAResultDO d2=lcaResultDOMapper.selectByPrimaryKey(id2);
            LCAResultDO d3=lcaResultDOMapper.selectByPrimaryKey(id3);
            LCAResultDO d6=lcaResultDOMapper.selectByPrimaryKey(id6);

            temp.setRaw(d1);
            temp.setPro_transport(d2);
            temp.setManufacture(d3);
            temp.setPro_recycle(d6);
            lists.add(temp);

        }
        return lists;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, rollbackFor = Exception.class)
    public void deleteById(Integer id) throws BusinessException {
        try{
            PartResultDO partResultDO = partResultDOMapper.selectByPrimaryKey(id);
            //先删除lca结果
            lcaResultDOMapper.deleteByPrimaryKey(partResultDO.getManufacturingStage());
            lcaResultDOMapper.deleteByPrimaryKey(partResultDO.getPartTransportationStage());
            lcaResultDOMapper.deleteByPrimaryKey(partResultDO.getRawmaterialMiningStage());
            lcaResultDOMapper.deleteByPrimaryKey(partResultDO.getRecoveryStage());
            //再删除Part结果
            partResultDOMapper.deleteByPrimaryKey(id);
        }catch (Exception e){
            throw new BusinessException(EmBusinessError.UNKNOWN_ERROR,"删除零件信息失败！");
        }

    }

    @Override
    public List<ResultNode> getMetaResult(Integer cal_id, Integer product_id) throws BusinessException {
        List<ResultNode> list=new ArrayList<>();

        List<PartResultDO> partResultDOS = partResultDOMapper.selectByCaliddAndProductid(cal_id, product_id);

        if(partResultDOS==null){
            throw new BusinessException(EmBusinessError.UNKNOWN_ERROR,"获取计算结果失败！");
        }

        for(PartResultDO i:partResultDOS){
            ResultNode temp=new ResultNode();

            Integer partid=i.getPartId();
            //查询该结果对应的零件
            ProductInfoDO productInfoDO=productInfoDOMapper.selectByPrimaryKey(partid);

            if(productInfoDO==null){
                throw new BusinessException(EmBusinessError.UNKNOWN_ERROR,"获取零件信息失败！");
            }
            temp.setName(productInfoDO.getNameInfo());
            temp.setOrderInfo(productInfoDO.getOrderInfo());
            temp.setSerialInfo(productInfoDO.getSerialInfo());
            temp.setMaterial(productInfoDO.getMaterialInfo());
            temp.setFunctionInfo(productInfoDO.getFunctionInfo());


            //设置零件的其他几个阶段的数据
            Integer id1=i.getRawmaterialMiningStage();
            Integer id2=i.getPartTransportationStage();
            Integer id3=i.getManufacturingStage();
            Integer id6=i.getRecoveryStage();

            //获取其他各个阶段的结果
            LCAResultDO d1=lcaResultDOMapper.selectByPrimaryKey(id1);
            LCAResultDO d2=lcaResultDOMapper.selectByPrimaryKey(id2);
            LCAResultDO d3=lcaResultDOMapper.selectByPrimaryKey(id3);
            LCAResultDO d6=lcaResultDOMapper.selectByPrimaryKey(id6);

            //计算PED
            BigDecimal ped=d1.getPed().add(d2.getPed()).add(d3.getPed()).add(d6.getPed());
            //计算GWP
            BigDecimal gwp=d1.getGwp().add(d2.getGwp()).add(d3.getGwp()).add(d6.getGwp());
            //计算AP
            BigDecimal ap=d1.getAp().add(d2.getAp()).add(d3.getAp()).add(d6.getAp());
            //计算EP
            BigDecimal ep=d1.getEp().add(d2.getEp()).add(d3.getEp()).add(d6.getEp());
            //计算POCP
            BigDecimal pocp=d1.getPocp().add(d2.getPocp()).add(d3.getPocp()).add(d6.getPocp());
            //计算ODP
            BigDecimal odp=d1.getOdp().add(d2.getOdp()).add(d3.getOdp()).add(d6.getOdp());
            //计算Green value
            BigDecimal greenvalue=d1.getGreenvalue().add(d2.getGreenvalue()).add(d3.getGreenvalue()).add(d6.getGreenvalue());

            temp.setGreenvalue(greenvalue);
            temp.setPed(ped);
            temp.setGwp(gwp);
            temp.setAp(ap);
            temp.setEp(ep);
            temp.setPocp(pocp);
            temp.setOdp(odp);
            Integer partId = i.getPartId();
            ProductInfoDO productInfoDO1 = productInfoDOMapper.selectByPrimaryKey(partId);
            if(productInfoDO==null){
                throw new BusinessException(EmBusinessError.UNKNOWN_ERROR,"查询结果失败!");
            }
            temp.setTransport(productInfoDO1.getTransportstyleInfo());
            temp.setManu(productInfoDO1.getManufacturestyleInfo());
            temp.setPercent(productInfoDO1.getRecycleInfo());

            temp.setRaw(d1.getGreenvalue());
            temp.setPro_transport(d2.getGreenvalue());
            temp.setManufacture(d3.getGreenvalue());
            temp.setRecycle(d6.getGreenvalue());

            list.add(temp);

        }
        return list;
    }

    public boolean judge(String a1,String a2){
        String[] a1s=a1.split("\\.");
        String[] a2s=a2.split("\\.");
        if(a1s.length>a2s.length){
            return true;
        }else if(a1s.length==a2s.length){
            for(int i=0;i<a1s.length;i++){
                if(a1s[i].equals(a2s[i])){
                    continue;
                }else{
                    Integer a11=Integer.parseInt(a1s[i]);
                    Integer a22=Integer.parseInt(a2s[i]);
                    return a11<a22;
                }
            }
        }else{
            return false;
        }
        return false;
    }



}
